package com.dave.gd.core.common;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;

import com.dave.gd.common.exception.RtManagerException;
import com.dave.gd.common.util.ClassInfoUtils;
import com.dave.gd.common.util.Constants;
import com.dave.gd.common.util.EntityInsFactory;
import com.dave.gd.common.util.MapUtils;
import com.dave.gd.core.base.entity.impl.AbstractBaseEntity;
import com.dave.gd.core.common.pagehelper.PageInfo;
import com.github.pagehelper.PageHelper;

@SuppressWarnings("rawtypes")
public class MybatisTemplate extends SqlSessionTemplate {
    
    public MybatisTemplate(SqlSessionFactory sqlSessionFactory) {
        super(sqlSessionFactory);
    }
    
    /**
     * 
     * 方法功能: 插入.
     * 
     * @param pojo
     * @return
     * @author: lzq
     * @修改记录：
     */
    public int insert(AbstractBaseEntity pojo) {
        int i = insert(pojo.getInsertMeth(), pojo);
        return i;
    }
    
    /**
     * 
     * 方法功能: 更新方法，并附带版本控制.
     * 
     * @param pojo
     * @return
     * @author: lzq
     */
    public int update(AbstractBaseEntity pojo) {
        return update(pojo.getUpdateMeth(), pojo);
    }
    
    /**
     * 
     * 方法功能: .
     * 
     * @param pojo
     * @return
     * @author: lzq
     */
    public int delete(AbstractBaseEntity pojo) {
        return delete(pojo.getDeleteMeth(), pojo);
    }
    
    /**
     * @param clazz
     * @param map
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T extends AbstractBaseEntity> AbstractBaseEntity getObjectByMap(Class<T> clazz,
        Map<String, Object> map) {
        AbstractBaseEntity pojo = (AbstractBaseEntity) EntityInsFactory.getInstance(clazz);
        //        map.put(Constants.POJO_KEY, pojo);
        map.put(Constants.POJO_KEY, clazz);
        PageHelper.startPage(1, 1, false);
        //        Map<String, Object> retMap = selectMap(pojo.getObjectByMapMeth(), map, pojo.id());
        Map<String, Object> retMap = selectMap(pojo.getObjectByMapMeth(), map,
            ClassInfoUtils.getIdField(clazz));
        if (retMap != null && !retMap.isEmpty()) {
            List<Object> list = new ArrayList<Object>(retMap.values());
            try {
                return (T) MapUtils.toObject(clazz, (Map) list.get(0), true);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RtManagerException(e);
            }
        }
        return null;
    }
    
    public <T extends AbstractBaseEntity> List<AbstractBaseEntity> getObjectListByMap(
        Class<T> clazz, Map<String, Object> map) {
        AbstractBaseEntity pojo = (AbstractBaseEntity) EntityInsFactory.getInstance(clazz);
        //        map.put(Constants.POJO_KEY, pojo);
        map.put(Constants.POJO_KEY, clazz);
        List<AbstractBaseEntity> retList = new ArrayList<AbstractBaseEntity>();
        
        List<Map<String, Object>> mapList = selectList(pojo.getObjectListByMapMeth(), map);
        if (mapList != null && !mapList.isEmpty()) {
            for (Map<String, Object> ret : mapList) {
                try {
                    retList.add((T) MapUtils.toObject(clazz, ret, true));
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RtManagerException(e);
                }
            }
        }
        return retList;
    }
    
    @SuppressWarnings("unchecked")
    public <T extends AbstractBaseEntity> PageInfo<T> getPageInfoByMap(Class<T> clazz,
        Map<String, Object> map, int pageNum, int pageSize) {
        AbstractBaseEntity pojo = (AbstractBaseEntity) EntityInsFactory.getInstance(clazz);
        //        map.put(Constants.POJO_KEY, pojo);
        map.put(Constants.POJO_KEY, clazz);
        PageHelper.startPage(pageNum, pageSize, true);
        
        List<Map<String, Object>> mapList = selectList(pojo.getPageInfoByMapMeth(), map);
        PageInfo pageInfo = new PageInfo(mapList);
        
        List<AbstractBaseEntity> retList = new ArrayList<AbstractBaseEntity>();
        
        if (mapList != null && !mapList.isEmpty()) {
            for (Map<String, Object> ret : mapList) {
                try {
                    retList.add((T) MapUtils.toObject(clazz, ret, true));
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RtManagerException(e);
                }
            }
        }
        pageInfo.setList(retList);
        return pageInfo;
    }
}
